﻿WEBVTT

00:00:00.000 --> 00:00:06.000
Translated by visionNoob, KNU
https://github.com/insurgent92/CS231N_17_KOR_SUB

00:00:14.752 --> 00:00:21.696
9강입니다. 오늘은 CNN 아키텍쳐들을
한번 알아보겠습니다.

00:00:21.696 --> 00:00:27.706
수업에 앞서 몇 가지 공지사항을 전달해 드리겠습니다.
우선 과제 2는 목요일까지 입니다.

00:00:27.706 --> 00:00:36.855
중간고사는 다음 주인 5월 9일 목요일 수업시간이 진행하도록 하겠습니다.
그 전까지 중간고사 범위 진도를 모두 나갈 예정입니다.

00:00:36.855 --> 00:00:41.350
Recurrent neural network 까지 차질없이
진행할 수 있도록 하겠습니다.

00:00:41.350 --> 00:00:49.121
그리고 우리 수업의 포스터세션이 6월 6일 12시부터 3시까지
진행될 예정입니다. 우리 수업의 마지막 주가 되겠군요

00:00:49.121 --> 00:00:53.828
이번에는 포스터세션이 조금 일찍 열립니다.

00:00:53.828 --> 00:01:00.132
포스터 세션까지 아직 시간이 남아있으니
기말 레포트에 최선을 다해주시기 바랍니다.

00:01:03.325 --> 00:01:05.812
지난 시간에 배운 내용을 복습해 보겠습니다.

00:01:05.812 --> 00:01:09.324
지난 시간에 다양한 딥러닝 프레임워크들을 배웠습니다.

00:01:09.324 --> 00:01:12.690
도PyTorch, TensorFlow, Caffe2 등이 있었죠

00:01:14.514 --> 00:01:18.762
이런 프레임워크를 이용하게 되면 NN, CNN같은 규모가 큰
computraional graphs를 아주 쉽게 구성할 수 있었습니다.

00:01:18.762 --> 00:01:25.784
또한 그래프에서 gradients을 계산하기에도
아주 수월했습니다.

00:01:25.784 --> 00:01:32.415
네트워크 중간의 가중치와 입력변수들의 그레디언트를
알아서 계산해 주기 때문에 Train에 사용만 하면 됩니다.

00:01:32.415 --> 00:01:35.665
그리고 이 모든 것을 GPU를 통해 아주 효율적으로
동작시킬 수 있습니다.

00:01:37.658 --> 00:01:44.978
그리고 프레임워크들은 대게 이런 식으로
모듈화된 레이어를 통해 동작합니다.

00:01:44.978 --> 00:01:49.928
여러분이 과제로 작성했던 backward/forward pass와
아주 유사한 모습입니다.

00:01:49.928 --> 00:01:58.404
모델 아키텍쳐를 구성하기 위해서는 단지 그 레이어들을
하나의 시퀀스로 정의하고 묶어주기만 하면 됩니다.

00:01:58.404 --> 00:02:04.937
이를 통해 아주 복잡한 아키텍쳐라고 해도
손쉽게 구성할 수 있습니다.

00:02:06.626 --> 00:02:14.520
오늘은 최신 CNN 아키텍쳐들에 대해서 배워보겠습니다.

00:02:14.520 --> 00:02:19.631
사람들이 가장 많이 사용하는 아키텍쳐들을
아주 심도깊게 살펴볼 것입니다.

00:02:19.631 --> 00:02:22.125
 이들은 모두 ImageNet 첼린지에서 우승한 모델들이죠

00:02:22.125 --> 00:02:28.085
여기에는 제가 연대순으로 정렬했습니다. AlexNet, VGGNet,
GoogLeNet 그리고 ResNet이 있습니다.

00:02:28.085 --> 00:02:43.771
그리고 또한 엄청 잘 사용하지는 않지만 역사적인 관점에서
아주 흥미로운 모델들, 그리고 아주 최신의 모델들도 다룰 것입니다.

00:02:46.822 --> 00:02:50.839
아주 오래 전 강의에서 LeNet을 다룬 적이 있었습니다.

00:02:50.839 --> 00:02:55.603
LeNet은 산업에 아주 성공적으로 적용된 최초의 ConvNet입니다.

00:02:55.603 --> 00:03:05.778
LeNet은 이미지를 입력으로 받아서 stride = 1 인 5 x 5 필터를
거치고 몇 개의 Conv Layer와 pooling layer를 거칩니다.

00:03:05.778 --> 00:03:09.335
그리고 끝 단에 FC Layer가 붙습니다.

00:03:09.335 --> 00:03:14.320
엄청 간단한 모델이지만 숫자 인식에서
엄청난 성공을 거두었습니다.

00:03:17.030 --> 00:03:22.875
2012년에 AlexNet이 나왔습니다. 이 모델도 이전 강의에서
다들 본 적 있으실 것ㅇ비니다.

00:03:22.875 --> 00:03:31.179
AlexNet은 최초의 Large scale CNN 입니다. ImageNet
Classification Task을 아주 잘 수행했습니다.

00:03:31.179 --> 00:03:40.611
AlexNet은 2012년에 등장해서는 기존의 non-딥러닝 모델들을
능가하는 놀라운 성능을 보여줬습니다.

00:03:40.611 --> 00:03:48.012
AlexNet은 ConvNet 연구의 부흥을 일으킨 장본입니다.

00:03:48.012 --> 00:03:56.427
AlexNet은 기본적으로 conv - pool - normalization
구조가 두 번 반복됩니다.

00:03:58.421 --> 00:04:01.006
그리고 conv layer가 조금 더 붙고(CONV 3,4,5)
그 뒤에 pooling layer가 있습니다. (Max POOL3)

00:04:01.006 --> 00:04:03.422
그리고 마지막에는 FC-layer가 몇 개 붙습니다.
(FC6, FC7, FC8)

00:04:03.422 --> 00:04:09.766
생긴 것만 봐서는 기존의 LeNet과 상당히 유사합니다.
레이어만 더 많아졌습니다.

00:04:09.766 --> 00:04:18.387
AlexNet는 5개의 Conv Layer와
2개의 FC-Layer로 구성됩니다.

00:04:21.889 --> 00:04:25.930
그렇다면 이제 AlexNet 의 모델 크기를 한번 살펴봅시다.

00:04:25.930 --> 00:04:33.128
AlexNet의 ImageNet으로 학습시키는 경우
입력의 크기가 227 x 227 x 3 입니다.

00:04:33.128 --> 00:04:43.193
AlexNet의 첫 레이어를 살펴보면 11 x 11 필터가
stride = 4 로 96개가 존재합니다.

00:04:43.193 --> 00:04:49.323
그렇다면 잠시 멈춰서 생각해봅시다.
첫 레이어의 출력사이즈는 어떻게 될까요?

00:04:51.788 --> 00:04:53.371
힌트도 있습니다.

00:04:57.769 --> 00:05:11.441
입력과 Conv 필터의 사이즈를 알고 있습니다.
그리고 출력값의 차원도 여기 힌트로 있습니다.

00:05:11.441 --> 00:05:17.632
이 공식은 (전체 이미지 크기 - 필터 크기) / Stride + 1 이죠

00:05:17.632 --> 00:05:26.919
결국 출력차원은 55입니다.
답이 뭘까요?

00:05:26.919 --> 00:05:29.823
[학생이 대답]

00:05:29.823 --> 00:05:32.966
55 x 55 x 96 이라고 답했습니다. 맞습니다.

00:05:32.966 --> 00:05:38.113
출력값의 width, height는 각각 55 입니다.

00:05:38.113 --> 00:05:45.391
그리고 필터가 총 96개 이므로 depth가 96이 됩니다.

00:05:45.391 --> 00:05:49.486
자 그러면 이 레이어의 전체 파라미터 갯수는 몇 개일까요?

00:05:49.486 --> 00:05:52.819
명심해야 할 점은
11 x 11 필터가 총 96개 있다는 것입니다.

00:05:54.851 --> 00:05:57.753
[학생이 대답]

00:05:57.753 --> 00:06:00.753
96 x 11 x11 이라고 답했습니다.
거의 맞췄습니다.

00:06:01.945 --> 00:06:05.297
네 맞습니다. 3을 더 곱해줘야죠

00:06:05.297 --> 00:06:13.632
필터 하나가 11 x 11 x 3 을 통과합니다.
입력의 Depth가 3이죠

00:06:13.632 --> 00:06:18.983
답은 전체 필터의 크기 X 96 이 됩니다.

00:06:18.983 --> 00:06:23.150
첫 레이어에 35K의 파라미터가 있는 것입니다.

00:06:26.018 --> 00:06:30.233
자 그러면 두 번째 레이어를 한번 살펴봅시다.
두 번째 레이어는 Pooling Layer 입니다.

00:06:30.233 --> 00:06:34.004
여기에는 stride = 2 인 3 x 3 필터가 있습니다.

00:06:34.004 --> 00:06:38.171
이 레이어의 출력값의 크기는 어떻게 될까요?

00:06:40.701 --> 00:06:44.868
힌트도 드렸습니다. 지난 문제와 아주 유사합니다.

00:06:51.251 --> 00:06:56.267
27 x 27 x 96 이라고 답했습니다.
네 맞습니다.

00:06:57.716 --> 00:07:01.528
Pooling Layer에서는 힌트에 나와있는 공식이
적용될 것입니다.

00:07:01.528 --> 00:07:16.655
이 공식을 이용해서 width, height를 구할 수 있습니다.
다만 depth는 입력과 변하지 않습니다.

00:07:16.655 --> 00:07:21.527
입력의 Depth가 96 이었으니 출력의 Depth도 96 입니다.

00:07:22.825 --> 00:07:28.127
그렇다면 이 레이어의 파라미터는 몇 개일까요?

00:07:31.446 --> 00:07:34.354
[학생이 대답]

00:07:34.354 --> 00:07:36.905
없다고 대답했습니다. 네 맞습니다.

00:07:36.905 --> 00:07:40.801
Pooling layer에는 파라미터가 없죠.
훼이크였습니다.

00:07:42.739 --> 00:07:45.272
네 질문있나요?

00:07:45.272 --> 00:07:47.192
[학생이 질문]

00:07:47.192 --> 00:07:52.180
질문은 바로 왜 pooling layer에는 파라미터가
없는지 입니다.

00:07:52.180 --> 00:07:54.551
파라미터는 우리가 학습시키는 가중치입니다.

00:07:54.551 --> 00:07:56.511
Conv Layer에는 학습할 수 있는 가중치가 있습니다.

00:07:56.511 --> 00:08:02.236
반면 pooling의 경우에는 가중치가 없고 그저
특정 지역에서 큰 값을 뽑아내는 역할만 합니다.

00:08:02.236 --> 00:08:05.710
따라서 학습시킬 파라미터가 없는 것이죠

00:08:05.710 --> 00:08:14.250
다들 집에가서 모든 레이어의 파라미터 사이즈를 계산해
보면 아주 큰 도움이 될 것입니다.

00:08:16.473 --> 00:08:22.688
이는 AlexNet의 전체 구조입니다.

00:08:22.688 --> 00:08:31.920
Conv layer들의 파라미터 크기는  앞서 계산한 값과 유사할 것입니다.

00:08:31.920 --> 00:08:39.122
그리고 끝에 몇 개의 FC-Layer가 있었습니다.
4096개의 노드를 가진 레이어입니다.

00:08:39.123 --> 00:08:41.540
그리고 FC8 는 Softmax를 통과합니다.

00:08:42.689 --> 00:08:46.356
1000 ImageNet 클래스로 이동합니다.

00:08:48.039 --> 00:08:56.352
AlexNet을 조금 더 자세히 살펴보자면 우선 ReLU 를 사용했습니다.
ReLU는 딥러닝 모델에서 아주 보편화된 방법입니다.

00:08:56.352 --> 00:09:07.391
local response normalization layer는 채널간의
 normalization을 위한 것인데 요즘은 잘 사용하지 않습니다.

00:09:07.391 --> 00:09:11.937
큰 효과가 없는 것으로 알려졌기 때문입니다.

00:09:11.937 --> 00:09:21.769
data augumentation을 엄청 했습니다. 논문이 더 자세하지만
flipping, jittering, color norm 등을 적용하였습니다.

00:09:21.769 --> 00:09:28.727
data augumentation은 여러분이 프로젝트를
진행할 때 아주 유용한 기법입니다.

00:09:28.727 --> 00:09:32.419
AlexNet은 Dropout을 사용했습니다.
학습 시 Batch size는 128 입니다.

00:09:32.419 --> 00:09:37.183
그리고 우리도 지난 강의에서 배웠던
SGD momentum을 사용했습니다.

00:09:37.183 --> 00:09:42.295
그리고 초기 Learning rate 는 1e-2 입니다.

00:09:42.295 --> 00:09:50.145
그리고 val accuracy가 올라가지 않는 지점에서는 학습이 종료되는
시점까지 Learning rate를 1e-10까지 줄입니다.

00:09:50.145 --> 00:09:59.012
그리고 wight decay를 사용했고, 마지막에는
모델 앙상블로 성능을 향상시켰습니다.

00:09:59.012 --> 00:10:03.162
그리고 여러개의 모델을 앙상블시켜서
성능을 개선했습니다.

00:10:04.405 --> 00:10:08.781
그리고 한가지 더 말씀드릴 점은 여기 AlexNet
다이어그램을 보시면

00:10:08.781 --> 00:10:15.235
대체로 다른 Conv Net의 다이어그램과 유사하긴 하지만
한 가지 차이점이 있습니다.

00:10:15.235 --> 00:10:21.937
그것은 바로 모델이 두개로 나눠져서 서로 교차하는 것입니다.

00:10:23.177 --> 00:10:32.905
역사적으로 들여다보면 AlexNet을 학습할 당시에 GTX850
으로 학습시켰습니다. 이 GPU는 메모리가 3GB 뿐이죠

00:10:34.106 --> 00:10:37.255
전체 레이어를 GPU에 다 넣을 수 없었습니다.

00:10:37.255 --> 00:10:41.773
그래서 네트워크를 GPU에 분산시켜서 넣었습니다.

00:10:41.773 --> 00:10:46.455
각 GPU가 모델의 뉴런과 Feature Map을 반반씩 나눠가집니다.

00:10:46.455 --> 00:10:51.730
첫 번째 레이어를 살펴보면 출력이 55 x 55 x 96입니다.

00:10:54.389 --> 00:11:04.155
다이어그램을 유심히 살펴보면 각 GPU에서의
Depth가 48이라는 것을 알 수 있습니다.

00:11:05.049 --> 00:11:08.593
Feature Map을 절반씩 가지고 있는 것이죠

00:11:10.288 --> 00:11:17.367
AlexNet의 Conv 1,2,4,5 에서
어떤 일이 발생하는지 살펴봅시다.

00:11:17.367 --> 00:11:29.683
여기에서는 같은 GPU 내에 있는 Feature Map만 사용합니다.
 Conv 1,2,4,5는 전체 96 feature map을 볼 수 없습니다.

00:11:29.683 --> 00:11:33.850
 Conv 1,2,4,5는 48개의 Feature Map만 사용하는 셈입니다.

00:11:34.767 --> 00:11:47.696
이제 conv 3와 FC 6, 7, 8 를 한번 살펴봅시다. 이 레이어들은
이전 계층의 "전체 Feature map"과 연결되어 있습니다.

00:11:47.696 --> 00:11:54.191
이 레이어들에서는 GPU간의 통신을 하기 때문에 이전 입력
레이어의 전체 Depth를 전부 가져올 수 있는 것입니다.

00:11:54.191 --> 00:11:55.627
질문있나요?

00:11:55.627 --> 00:12:01.442
[학생이 질문]

00:12:05.583 --> 00:12:10.033
질문은 왜 여기에 예시가 full "simplified"
AlexNet architecture 인지 입니다.

00:12:10.033 --> 00:12:19.036
Simplified 라고 하는 이유는 여기에 AlexNet의
세부적인 것들을 전부 표시하지 않았기 때문입니다.

00:12:19.036 --> 00:12:25.268
가령  normalization layer 같은 경우에
자세히 기입해 놓지 않았습니다.

00:12:30.637 --> 00:12:37.849
그리고 AlexNet 논문의 아키텍쳐와 관련한 조그만
이슈가 하나 있습니다.

00:12:38.858 --> 00:12:52.721
논문의 그림에서는 첫 레이어가 224 x 224 라고 되어 있습니다.
하지만 실제 입력은 227 x 227 입니다.

00:12:54.982 --> 00:13:04.261
AlexNet은 Image Classification Benchmark의
2012년도에 우승한 모델입니다.

00:13:05.246 --> 00:13:14.193
AlexNet은 최초의 CNN기반 우승 모델이고 수년 전까지 대부분의
CNN 아키텍쳐의 베이스모델로 사용되어 왔습니다.

00:13:15.720 --> 00:13:17.980
물론 아직까지도 꽤 사용합니다.

00:13:17.980 --> 00:13:24.071
AlexNet은 다양한 Task의 transfer learning에 많이
사용되었습니다. 아주 오랜 시간 많은 사람들이 사용했고 -

00:13:24.071 --> 00:13:33.202
정말 유명한 모델이었습니다. 지금은 더 최신의 아키텍쳐가 많습니다.
일반적으로 AlexNet보다 성능이 더 뛰어나죠.

00:13:33.202 --> 00:13:39.282
이제는 더 최신의 모델들에 대해 살펴보겠습니다. 여러분이
실제도 더 자주 사용하게될 모델들입니다.

00:13:40.853 --> 00:13:47.813
그리고 2013년의 ImageNet Challange의 승자는
ZFNet 이라는 모델입니다.

00:13:47.813 --> 00:13:48.718
질문있나요?

00:13:48.718 --> 00:13:52.729
[학생이 질문]

00:13:52.729 --> 00:13:56.612
질문은 AlexNet이 기존의 모델들보다 뛰어날 수 있었던
이유가 무엇인지 입니다.

00:13:56.612 --> 00:14:04.786
이는 딥러닝와 Conv Net 때문입니다.
이들은 기존의 방법들과 완전히 다른 접근방법입니다.

00:14:04.786 --> 00:14:09.004
AlexNet이 최초로 딥러닝과 Conv Net을 적용하였습니다.

00:14:12.445 --> 00:14:18.298
2013년에는 ZFNet이 우승트로피를 획득했습니다.
ZF는 저자들의 이름을 딴 명칭입니다.

00:14:18.298 --> 00:14:23.749
ZFNet은 대부분 AlexNet의 하이퍼파라미터를 개선한 모델입니다.

00:14:23.749 --> 00:14:35.735
AlexNet과 같은 레이어 수이고 기존적인 구조도 같습니다.
다만 stride size, 필터 수 같은 하이퍼파라미터를 조절해서-

00:14:35.735 --> 00:14:41.369
AlexNet의 Error rate를 좀 더 개선시켰습니다.
AlexNet의 아이디어와는 기본적으로 같습니다.

00:14:41.369 --> 00:14:49.843
2014년에는 많은 변화가 있었습니다. 아키텍쳐도 많이 변했고
성능을 훨씬 향상되었죠

00:14:49.843 --> 00:14:58.178
가장 큰 차이점이라면 우선 네트워크가 훨씬 더 깊어졌다는 것입니다.

00:14:58.178 --> 00:15:12.321
2012/2013년에는 8개의 레이어였습니다. 하지만 2014년에는
19레이어와 22 레이어로 늘어났습니다. 훨씬 더 깊어졌죠

00:15:12.321 --> 00:15:16.502
2014년도의 우승자는 Google의 GoogLenet이었습니다.

00:15:16.502 --> 00:15:20.176
그리고 Oxford의 VGGNet이 2등을 차지했죠

00:15:20.176 --> 00:15:27.421
VGGNet은 Localization Challenge 등 일부 다른
트랙에서는 1위를 차지했습니다.

00:15:27.421 --> 00:15:31.958
이 둘 모두 아주 강력한 네트워크입니다.

00:15:31.958 --> 00:15:34.663
우선 VGG을 한번 살펴봅시다.

00:15:34.663 --> 00:15:40.818
VGGNet의 특징은 우선 훨씬 더 깊어졌고
그리고 더 작은 필터를 사용한다는 것입니다.

00:15:40.818 --> 00:15:50.374
AlexNet에서는 8개의 레이어였지만 VGGNet은
16에서 19개의 레이어를 가집니다.

00:15:52.290 --> 00:16:03.916
그리고 VGGNet은 아주 작은 필터만 사용합니다. 항상 3 x 3 필터만
사용합니다. 이웃픽셀을 포함할 수 있는 가장 작은 필터입니다.

00:16:03.916 --> 00:16:11.485
이렇게 작은 필터를 유지해 주고 주기적으로 Pooling을
수행하면서 전체 네트워크를 구성하게 됩니다.

00:16:11.485 --> 00:16:19.948
VGGNet은 아주 심플하면서도 고급진 아키텍쳐이고
ImageNet에서 7.3%의 Top 5 Error를 기록했습니다.

00:16:22.651 --> 00:16:27.442
그렇다면 VGGNet은 왜 더 작은 필터를 사용했을까요?

00:16:27.442 --> 00:16:33.371
우선 필터의 크기가 작으면 파라미터의 수가 더 적습니다.
따라서 큰 필터에 비해 레이어를 조금 더 많이 쌓을 수 있겠죠

00:16:33.371 --> 00:16:39.344
다시 말해 작은 필터를 사용하면 Depth를 더 키울 수 있는 것입니다.

00:16:39.344 --> 00:16:47.202
3 x 3 필터를 여러 개 쌓은 것은 결국 7 x 7 필터를 사용하는 것과
실질적으로 동일한 Receptive Filter를 가지는 것입니다.

00:16:47.202 --> 00:16:55.466
그렇다면 질문입니다. stride = 1 인 3 x 3필터를 세 개의
Receptive Filed는 어떻게 될까요?

00:16:55.466 --> 00:17:01.189
Stride가 1인 필터 세 개를 쌓게 되면
실질적인 Receptive Field가 어떻게 될까요?

00:17:01.189 --> 00:17:09.754
Receptive Field은 filter가 한번에 볼 수 있는 입력의
"Sparical area" 입니다.

00:17:12.313 --> 00:17:15.987
누군가가 15 픽셀이라고 했습니다.
왜 15 필셀인가요?

00:17:15.987 --> 00:17:20.609
[학생이 대답]

00:17:20.609 --> 00:17:27.369
네 맞습니다 필터들이 서로 겹치는 것입니다.

00:17:27.369 --> 00:17:35.668
실제로 어떤 일이 발생하는지 한번 살펴봅시다. 우선 첫 번째
레이어의 Receptive Field는 3 x 3 입니다.

00:17:35.668 --> 00:17:43.193
두 번째 레이어의 경우는 각 뉴런이 첫 번째 레이어 출력의
3 x 3 만큼을 보게 될 것입니다.

00:17:43.193 --> 00:17:51.676
그리고 3 x 3 중에 각 사이드는 한 픽셀씩 더 볼 수 있게 됩니다.

00:17:51.676 --> 00:17:56.423
따라서 두번째 레이어의 경우는 실제로
5 x 5의 receptive filed를 가지게 되는 것입니다.

00:17:56.423 --> 00:18:04.040
세 번째 레이어의 경우 두 번째 레이어의 3 x 3 을 보게됩니다.

00:18:04.040 --> 00:18:06.907
그리고 이 과정을 피라미드처럼 그려보면
결국 입력 레이어의 7 x 7을 보게되는 것이죠

00:18:06.907 --> 00:18:16.026
따라서 실질적인 Receptive Field는 여기에서 7 x 7 이 됩니다.
하나의 7 x 7 필터를 사용하는 것과 동일합니다.

00:18:16.026 --> 00:18:21.546
따라서 이는 7 x 7 필터와 실직적으로 동일한 receptive
filed를 가지면서도 더 깊은 레이어를 쌓을 수 있게 됩니다.

00:18:21.546 --> 00:18:26.201
더 깊게 쌓으므로써 Non-Linearity를 더 추가할 수 있고
파라미터 수도 더 적어지게 됩니다.

00:18:26.201 --> 00:18:36.536
전체 파라미터의 갯수를 살펴보면 3 x 3 필터에는
9개의 파라미터가 있습니다.

00:18:38.165 --> 00:18:44.648
3 x 3  가 되죠 그리고 Depth인 C가 있으니
3 x 3 x C 가 됩니다.

00:18:44.648 --> 00:18:51.034
그리고 출력 Feature Map의 갯수를 곱해줘야 하는데
이 경우에는 입력 Depth와 같습니다. C이죠

00:18:51.034 --> 00:19:00.165
따라서 각 레이터 당 3 x 3 x C x C 가 됩니다. 그리고 레이어가
세개 이므로 3을 더 곱해줍니다.

00:19:00.165 --> 00:19:07.409
 7 x 7 필터인 경우에는 7 x 7 x C x C 입니다.

00:19:07.409 --> 00:19:11.032
따라서 더 적은 파라미터를 가지게 됩니다.

00:19:15.570 --> 00:19:24.161
이제 전체 네트워크를 한번 살펴보도록 하겠습니다. 여기 숫자가
너무 많죠 다들 집으로 돌아가서 유심히 살펴보시기 바랍니다.

00:19:24.161 --> 00:19:30.716
AlexNet에서 우리가 계산해 봤던 것 처럼 파라미터의
크기와 수를 계산해 보실 수 있을 것입니다.

00:19:30.716 --> 00:19:32.517
연습으로 해보시면 아주 좋습니다.

00:19:32.517 --> 00:19:45.834
비슷한 패턴이 반복됩니다. Conv Layer와 Pooling Layer가
반복적으로 진행되는 것이죠

00:19:45.834 --> 00:19:52.431
VGG16에서 모든 Layer의 수를 세어보면 16개 입니다.

00:19:52.431 --> 00:20:00.478
VGG19의 경우 유사한 아키텍쳐이지만 Conv Layer가
조금 더 추가되었습니다.

00:20:03.021 --> 00:20:05.605
네트워크이 전체 메모리 사용량을 살펴봅시다.

00:20:05.605 --> 00:20:17.196
Forward pass 시 필요한 전체 메모리를 계산한 것입니다.

00:20:17.196 --> 00:20:23.125
그리고 각 노드가 4 bytes 의 메모리를 차지하므로
전체 약 100 MB의 메모리가 필요합니다.

00:20:23.125 --> 00:20:28.727
100MB가 전체 메모리 사용량이죠. 하지만 이 값은
Forward Pass 만 계산한 것입니다.

00:20:28.727 --> 00:20:35.470
Backward Pass를 고려한다면 더 많은 메모리가 필요할 것입니다.
VGG16은 메모리사용량이 많은 편입니다.

00:20:35.470 --> 00:20:44.410
전체 메모리가 5GB라면 이미지 하나당 100MB이므로
50장 밖에 처리할 수 없습니다.

00:20:47.300 --> 00:20:56.131
그리고 전체 파라미터의 갯수는 138M 개 입니다.
AlexNet의 경우에는 60M 개었죠

00:20:56.131 --> 00:20:57.481
질문있나요?

00:20:57.481 --> 00:21:00.898
[학생이 질문]

00:21:06.204 --> 00:21:09.920
질문은 "네트워크가 더 깊다"는게  "필터의 갯수가 더 많은 것"을
의미하는 것인지 "레이어의 갯수가 더 많은 것"을 의미하는 것인지 입니다.

00:21:09.920 --> 00:21:14.087
이 경우에는 레이어의 갯수를 의미합니다.

00:21:15.605 --> 00:21:25.216
Depth 라는 용어는 두 가지도 사용할 수 있습니다. 첫 째로는 채널의
Depth입니다. Width, Height, Depth 할때 Depth이죠

00:21:26.942 --> 00:21:34.298
반면 일반적으로 "네트워크의 깊이(Depth)"라고 할 때는
네트워크의 전체 레이어의 갯수 를 의미합니다.

00:21:34.298 --> 00:21:43.368
"학습 가능한 가중치를 가진 레이어의 갯수" 를 의미합니다.
가령 Conv Layer와 FC Layer 등 말입니다.

00:21:43.368 --> 00:21:46.868
[학생이 질문]

00:22:00.810 --> 00:22:06.174
질문은 하나의 Conv Layer 내에 여러개의 필터가 존재하는
이유가 무엇인지 입니다.

00:22:06.174 --> 00:22:13.043
지난 Conv Net 강의에서 다룬 적이 있습니다. 집에 돌아가서
한번 참고해 보시는 것이 좋을 것 같습니다. 어쩄든 -

00:22:13.043 --> 00:22:27.616
3 x 3 Conv 필터가 있다고 해봅시다. 필터는 한번에
3 x 3 x Depth를 보고 하나의 Feature Map을 만들어냅니다.

00:22:27.616 --> 00:22:31.954
그리고 입력 전체를 돌면서 하나의 Feature Map을
완성시킵니다.

00:22:31.954 --> 00:22:39.646
우리는 여러개의 필터를 사용할 수 있습니다. 가령 96개를 사용할 수
있겠죠. 그리고 각 필터는 하나의 Feature Map을 만듭니다.

00:22:39.646 --> 00:22:48.368
그리고 각 필터가 존재하는 이유는 서로 다른 패턴을
인식하기 위해서 라고 할 수 있습니다.

00:22:48.368 --> 00:22:56.181
각 필터는 각각의 Feature Map을 만들게 되는 것입니다.

00:22:58.761 --> 00:23:00.226
질문있나요?

00:23:00.226 --> 00:23:03.643
[학생이 질문]

00:23:07.465 --> 00:23:16.733
질문은 "네트워크가 깊어질수록 레이어의 필터 갯수를 늘려야
하는지" 입니다.(Channel Depth를 늘려야 하는지)

00:23:17.676 --> 00:23:21.766
여러분이 디자인하기 나름이고 반드시 그럴 필요는 없습니다.

00:23:21.766 --> 00:23:24.341
하지만 실제로 사람들이 Depth를 많이 늘리는 경우가 많습니다.

00:23:24.341 --> 00:23:30.598
Depth를 늘리는 이유 중 하나는 계산량을 일정하게 유지시키기
위해서 입니다(constant level of compute).

00:23:30.598 --> 00:23:37.991
보통 네트워크가 깊어질수록 각 레이어의 입력을
Down sampling하게 됩니다.

00:23:39.606 --> 00:23:45.759
Spatial area가 작아질수록 필터의 depth를
조금씩 늘려주게 됩니다.

00:23:45.759 --> 00:23:53.367
Width Height가 작아지기 때문에 Depth를 늘려도
부담이 없습니다.

00:23:53.367 --> 00:23:54.716
질문있나요?

00:23:54.716 --> 00:23:58.133
[학생이 질문]

00:23:59.872 --> 00:24:04.653
질문은 네트워크에 SoftMax Loss 대신
SVM Loss를 사용해도 되는지 입니다.

00:24:04.653 --> 00:24:09.761
지난 강의에서 다룬 내용입니다만
둘 다 사용할 수 있습니다.

00:24:09.761 --> 00:24:17.242
하지만 보통 SoftMax Loss를 일반적으로 사용하는 편입니다.

00:24:18.509 --> 00:24:20.023
네 질문있나요?

00:24:20.023 --> 00:24:23.523
[학생이 질문]

00:24:37.902 --> 00:24:45.398
질문은 "앞서 계산한 메모리 중에 굳이 가지고 있지 않고
버려도 되는 부분이 있는지" 입니다.

00:24:45.398 --> 00:24:49.221
예 맞습니다.
일부는 굳이 가지고있지 않아도 됩니다.

00:24:49.221 --> 00:25:02.571
하지만 Backword pass시 chain rule을 계산할 때
대부분은 이용됩니다. 따라서 대부분은 반드시 가지고있어야겠죠

00:25:04.006 --> 00:25:14.440
파라미터가 존재하는 곳들의 메모리 사용분포를 살펴보면
초기 레이어에서 많은 메모리를 사용하는 것을 알 수 있습니다.

00:25:14.440 --> 00:25:24.054
Sparial dimention이 큰 곳들이 메모리를 더 많이 사용합니다.
그리고 마지막 레이어는 많은 파라미터를 사용합니다.

00:25:24.054 --> 00:25:28.837
FC-Layer이엄청난 양의 파라미터를 사용합니다.
dense connection이기 때문이죠

00:25:28.837 --> 00:25:36.999
그리고 나중에 더 알아보겠지만 최근에 일부 네트워크들은

00:25:36.999 --> 00:25:42.345
아얘 FC Layer를 없애버리기도 합니다.
너무 많은 파라미터를 줄이기 위해서죠

00:25:42.345 --> 00:25:48.059
그리도 또 한가지 말씀드릴 점은 여기에 각 레이어들을
부르는 명칭이 있을 수 있습니다.

00:25:48.059 --> 00:25:56.190
제가 여기에 써 놓은것 처럼 conv3-64는
64개의 필터를 가진 3 x 3 conv 필터입니다.

00:25:56.190 --> 00:26:05.190
그리고 다이어그램의 오른쪽을 보시면 각 필터를 묶어놓았습니다.
사람들이 많이 쓰는 방법입니다.

00:26:05.190 --> 00:26:11.822
여기 오렌지색 블락을 보시면 첫번째 그룹(part 1)의
conv들은 conv1-1, conv1-2 이렇게 표현합니다.

00:26:11.822 --> 00:26:14.655
알고계시면 좋습니다.

00:26:16.594 --> 00:26:22.120
VGGNet은 ImageNet 2014 Classification
Challenge에서 2등을 했습니다.

00:26:22.120 --> 00:26:24.783
Localization에서는 우승을했죠

00:26:24.783 --> 00:26:29.037
학습 과정은 AlexNet과 유사합니다.

00:26:29.037 --> 00:26:38.764
다만 Local response normalization은 사용하지 않습니다.
앞서 언급했듯 도움이 크게 안되기 떄문이었죠

00:26:38.764 --> 00:26:49.615
VGG16과 VGG19은 아주 유사합니다. 다만 VGG19가
조금 더 깊을 뿐이죠

00:26:49.615 --> 00:27:00.366
VGG19가 아주 조금 더 좋습니다. 메모리도 조금 더 쓰죠.  여러분은
두 모델 모두 사용할 수 있겠지만 보통 16을 더 많이 사용합니다.

00:27:01.470 --> 00:27:10.110
그리고 AlexNet에서 처럼 모델 성능을 위해서 앙상블 기법을 사용했습니다.

00:27:10.110 --> 00:27:20.158
그리고 VGG의 마지막 FC-Layer인 FC7은 이미지넷 1000 class
의 바로 직전에 위치한 레이어입니다.

00:27:20.158 --> 00:27:26.463
이  FC7은 4096 사이즈의 레이어인데 아주 좋은
feature represetation을 가지고 있는 것으로 알려져있습니다.

00:27:26.463 --> 00:27:35.055
다른 데이터에서도 특징(feature) 추출이 잘되며
다른 Task에서도 일반화 능력이 뛰어난 것으로 알려져있습니다.

00:27:35.055 --> 00:27:37.792
FC7은 아주 좋은 feature representation입니다.

00:27:37.792 --> 00:27:39.142
예 질문있나요?

00:27:39.142 --> 00:27:44.432
[학생이 질문]

00:27:45.939 --> 00:27:50.036
질문은 "localization이 무엇인지" 입니다.
(VGG가 localization task에서 우승)

00:27:50.036 --> 00:27:57.163
localization은 task입니다. 나중 강의에서 Detection과
Localization을 다룰 예정입니다.

00:27:57.163 --> 00:28:03.205
여기에서 더 자세히 말씀드리지는 않겠지만 기본적으로
"이미지에 고양이가 있는지?" 를 분류하는 것 뿐만 아니라

00:28:03.205 --> 00:28:09.433
정확히 고양이가 어디에 있는지 네모박스를
그리는 것입니다.

00:28:09.433 --> 00:28:16.153
Detection과는 조금 다릅니다. Detection은 이미지 내에
다수의 객체가 존재할 수 있습니다.

00:28:16.153 --> 00:28:22.671
localization은 이미지에 객체가 하나만 있다고 가정하고
이미지를 분류하고 추가적으로 네모박스도 쳐야합니다.

00:28:25.343 --> 00:28:32.382
지금까지는 VGGNet에 대해서 알아보았습니다. 이제는
GoogLeNet에 대해서 알아보겠습니다.

00:28:32.382 --> 00:28:36.603
2014년 Classification Challenge에서 우승한 모델입니다.

00:28:37.612 --> 00:28:47.776
저GoogLeNet도 엄청 깊은 네트워크입니다. 22개의 레이어를 가지고있죠.
그런데 GoogLeNet에서 가장 중요한 것은

00:28:47.776 --> 00:28:57.866
효율적인 계산에 관한 그들의 특별한 관점이 있다는 것과 높은 계산량을
아주 효율적으로 수행하도록  네트워크를 디자인했다는 점입니다.

00:28:57.866 --> 00:29:05.023
GoogLeNet은 Inception module을 사용합니다. 앞으로 더
깊이 배울 내용입니다. 기본적으로 GoogLeNet은

00:29:05.023 --> 00:29:08.336
Inception module을 여러개 쌓아서 만듭니다.

00:29:08.336 --> 00:29:19.841
GoogLeNet에는 FC-Layer가 없습니다. 파라미터를 줄이기 위해서죠.
전체 파라미터 수가 5M 정도입니다. 60M인 AlexNet보다 적죠

00:29:19.841 --> 00:29:24.308
그럼에도 불구하고 훨씬 더 깊습니다.

00:29:24.308 --> 00:29:26.975
 ILVRC 14에서 6.7%의 top-5 error로 우승을 거머쥡니다.

00:29:31.392 --> 00:29:35.363
그렇다면 inception module이 무엇일까요?
inception module가 만들어지게된 배경을 살펴보면

00:29:35.363 --> 00:29:40.023
그들은 "a good local network typology"를
디자인하고 싶었습니다.

00:29:40.023 --> 00:29:52.341
그리고 "network within a network" 라는 개념으로
local topology를 구현했고 이를 쌓아올렸습니다.

00:29:52.341 --> 00:29:58.387
이 Local Network를 Inception Module이라고 합니다.

00:29:58.387 --> 00:30:07.138
Inception Module 내부에는 동일한 입력을 받는 서로 다른
다양한 필터들이 "병렬로" 존재합니다.

00:30:07.138 --> 00:30:11.896
이전 레이어의 입력을 받아서 다양한 Conv 연산을 수행하는 것이죠

00:30:11.896 --> 00:30:25.647
1x1 / 3x3 / 5x5 conv에 Pooling도 있습니다. 여기에서는
3x3 pooling이죠 각 레이어에서 각각의 출력 값들이 나오는데

00:30:25.647 --> 00:30:31.499
그 출력들을 모두 Depth 방향으로 합칩니다(concatenate).

00:30:31.499 --> 00:30:38.893
그렇게 합치면 하나의 tensor로 출력이 결정되고
이 하나의 출력을 다음 레이어로 전달하는 것입니다.

00:30:41.020 --> 00:30:50.015
지금까지는 다양한 연산을 수행하고 이를 하나로 합쳐준다는
아주 단순한 방식(naive way)을 살펴봤습니다.

00:30:50.015 --> 00:30:52.386
그렇다면 이 방법의 문제가 무엇일까요?

00:30:52.386 --> 00:30:57.717
문제는 바로 계산 비용에 있습니다.

00:30:58.982 --> 00:31:11.156
예제를 자세히 들여다봅시다. 우선 128개의 1x1 필터가 있습니다.
192개의 3x3 필터와 96개의 5x5 필터도 있습니다.

00:31:11.156 --> 00:31:19.398
그리고 stride를 조절하여 입/출력 간의
spatial dimention을 유지시켜줍니다.

00:31:21.341 --> 00:31:29.231
이 경우에 1 x 1 x 128 conv의 출력은 어떻게 될까요?

00:31:35.910 --> 00:31:39.910
네 맞습니다. 28 x 28 x 128이 되겠죠.

00:31:40.988 --> 00:31:53.159
1x1 conv의 경우 입력에 맞춰 depth는 256입니다.

00:31:53.159 --> 00:32:00.194
그리고 128개의 필터 하나 당 28 x 28 Feature map을
생성하게 될 것입니다.

00:32:00.194 --> 00:32:02.361
그렇다면 출력은 28 x 28 x 128 이 되겠죠

00:32:05.469 --> 00:32:14.939
이런 방식으로 각 필터의 출력 값을 계산해보면

00:32:14.939 --> 00:32:20.379
3 x 3 conv의 경우에 출력이 28 x 28 x 192이 될 것이고

00:32:20.379 --> 00:32:24.559
5 x 5 conv의 경우에 96개의 필터이므로
 출력이 28 x 28 x 96 이 될 것입니다.

00:32:24.559 --> 00:32:34.712
Pooling Layer는 input에서 depth가 변하지 않습니다.

00:32:34.712 --> 00:32:40.192
그리고 Stride를 잘 조절해서 Spatial dimention를
유지하면 입력과 출력의 크기는 같습니다.

00:32:41.225 --> 00:32:51.498
그렇다면 모든 출력 값들을 합친(concat) 사이즈를 계산해봅시다.
28 x 28 은 동일하고 depth가 점점 쌓이게 됩니다.

00:32:51.498 --> 00:32:59.330
28 x 28 에 모든 depth를 더하면
최종적으로 28 x 28 x 672이 됩니다.

00:33:01.113 --> 00:33:10.208
Inception module의 입력은 28 x 28 x 256 이었으나
출력은 28 x 28 x 672 이 된 것입니다.

00:33:11.466 --> 00:33:17.254
spatial dimention은 변하지 않았지만
depth가 엄청나게 불어난 것이죠

00:33:17.254 --> 00:33:18.188
질문있나요?

00:33:18.188 --> 00:33:21.905
[학생이 질문]

00:33:21.905 --> 00:33:25.546
질문은 어떻게 출력의 spatial dimention이
28 x 28이 될 수 있는지 입니다.

00:33:25.546 --> 00:33:29.307
이 경우는 spatial dimention을 유지하기 위해서
zero padding을 한 경우입니다.

00:33:29.307 --> 00:33:33.403
그리고 depth-wise로 합쳤습니다(concat).

00:33:34.395 --> 00:33:36.233
질문있나요?

00:33:36.233 --> 00:33:39.650
[학생이 질문]

00:33:44.824 --> 00:33:47.805
질문은 입력의 depth가 256인 이유가 무엇인지 입니다.

00:33:47.805 --> 00:33:53.814
현재 입력은 네트워크의 입력이 아닙니다. 네트워크
중간에 있는 어떤 한 레이어의 입력인 것이죠

00:33:53.814 --> 00:34:00.506
256이라는 값은 바로 직전에 있던 inception module의
출력 depth라고 할 수 있습니다.

00:34:00.506 --> 00:34:08.438
현재 레이어의 출력이 28 x 28 x 672 이었습니다.
이 값이 다음 레이어로 넘어가는 것입니다 .

00:34:08.438 --> 00:34:09.915
질문있나요?

00:34:09.916 --> 00:34:13.333
[학생이 질문]

00:34:17.039 --> 00:34:23.181
질문은 어떻게 1 x 1 conv의 출력이
28 x 28 x 128이 되는지 입니다.

00:34:23.181 --> 00:34:34.058
이 필터는 1 x 1 conv 필터입니다. 이 필터가
입력 28 x 28 x 256 돌아다니면서 conv연산을 수행하겠죠

00:34:35.485 --> 00:34:41.956
1 x 1 conv는 입력의 depth인 256 만 가지고
내적을 한다고 보시면 됩니다.

00:34:41.956 --> 00:34:46.983
그렇게 되면 필터 하나 당 28 x 28 x 1 의
feature map을 얻게 될 것입니다.

00:34:46.983 --> 00:34:58.311
다시 말해 입력의 각 픽셀마다 값이 하나 씩 계산됩니다.
그러면 필터당 28 x 28 x 1이 되겠죠. 그리고 필터가 128개 입니다.

00:35:01.050 --> 00:35:04.800
따라서 28 x 28 x 128 이 되는 것입니다.

00:35:05.809 --> 00:35:10.403
그리고 이 레이어들의 계산량을 한번 살펴봅시다

00:35:10.403 --> 00:35:22.553
첫 번째 예시로 1 x 1 conv를 살펴봅시다. 1 x 1 conv는
각 픽셀마다 1 x 1 x 256 개의 내적연산을 수행합니다.

00:35:24.545 --> 00:35:28.358
따라서 픽셀 당 256번의 곱셈 연산이 수행되는 것이죠
(Conv Ops:맨 뒤의 256)

00:35:28.358 --> 00:35:37.865
그리고 픽셀이 총 28 x 28 이므로
처음 "28  x 28" 이 여기에 해당합니다.

00:35:37.865 --> 00:35:53.859
그리고 이런 연산을 수행하는 필터가 총 256개 있으므로

00:35:53.859 --> 00:36:01.221
1 x 1 conv에서의 전체 연산량은
28 x 28 x 128 x 256 입니다.

00:36:02.129 --> 00:36:10.349
이런 식으로 3x3/5x5 conv 의 연산량도 계산해 볼 수 있습니다.

00:36:10.349 --> 00:36:16.690
따라서 하나의 Inception Module에서의
전체 연산량은 854M 가 됩니다.

00:36:17.968 --> 00:36:21.191
[학생이 질문]
각 필터의 depth인 128, 192, 96이 의미가 있는지

00:36:22.131 --> 00:36:29.044
이 값들을 제가 임의로 정한 값들입니다.

00:36:29.044 --> 00:36:35.594
하지만 실제 Inception Net에서도 비슷한 값이긴 합니다.

00:36:35.594 --> 00:36:43.103
GoogLeNet의 각 Inception Module에는 파라미터 값이
다양하기 때문에 그 중 일부를 참고한 값들입니다.

00:36:45.089 --> 00:36:49.046
아무튼 이는 연산량이 아주 많습니다.

00:36:49.046 --> 00:36:55.507
그리고 Pooling layer 또한 문제를 악화시킵니다. 왜냐하면
입력의 Depth를 그대로 유지하기 때문입니다.

00:36:57.062 --> 00:37:03.519
레이어를 거칠때마다 Depth가 점점 늘어만 갑니다.

00:37:03.519 --> 00:37:10.513
Pooling의 출력은 이미 입력의 Depth와 동일하고 여기에
다른 레이어의 출력이 계속해서 더해지게 되는 것입니다.

00:37:10.513 --> 00:37:18.960
이 경우에는 입력의 Depth는 256이었지만 출력은 672이 됩니다.
그리고 레이어를 거칠수록 점점 더 늘어나게 되는 것이죠

00:37:21.920 --> 00:37:25.441
이 문제를 어떻게 해결할 수 있을까요?

00:37:25.441 --> 00:37:36.181
GoogLeNet에서 사용한 key insight는 "bottleneck
layer" 를 이용하는 것입니다. Conv 연산을 수행하기에 앞서

00:37:36.181 --> 00:37:43.174
입력을 더 낮은 차원으로 보내는 것이죠

00:37:45.007 --> 00:37:46.642
낮은 차원으로 보낸다는 것이 어떤 의미일까요?

00:37:46.642 --> 00:37:58.080
1x1 conv를 다시 한번 살펴봅시다. 1x1 conv는 각
spatial location에서만 내적을 수행합니다.

00:38:00.141 --> 00:38:06.139
그러면서 depth만 줄일 수 있습니다. 입력의 depth를
더 낮은 차원으로 projection 하는 것입니다.

00:38:06.139 --> 00:38:10.515
Input feature map들 간의
선형결합(linear combination) 이라고 할 수 있습니다.

00:38:12.880 --> 00:38:18.199
주요 아이디어는 바로 입력의 depth를 줄이는 것입니다.

00:38:18.199 --> 00:38:29.085
각 레이어의 계산량은 1x1 conv를 통해 줄어듭니다.

00:38:29.085 --> 00:38:36.162
3x3/5x5 conv 이전에 1x2이 추가됩니다.

00:38:36.162 --> 00:38:42.315
그리고 polling layer 후에도 1x1 conv가 추가되죠

00:38:43.284 --> 00:38:47.609
1x1 conv가 bottleneck layers의 역할로 추가되는 것입니다.

00:38:48.562 --> 00:38:52.736
그렇다면 다시한번 계산량을 세어봅시다

00:38:52.736 --> 00:38:58.589
우선 이전과 입력은 동일합니다.
28 x 28 x 256 이죠

00:38:58.589 --> 00:39:12.856
1 x 1 conv가 depth 의 차원을 줄여줍니다. 3 x 3 conv
앞쪽의 1 x 1 conv의 출력은 28 x 28 x 64 이죠

00:39:14.184 --> 00:39:25.154
앞선 예시 처럼 28 x 28 x 256 을 입력인 대신에
28 x 28 x 64인 것입니다. .

00:39:25.154 --> 00:39:31.454
conv의 입력이 더 줄어든 셈입니다.

00:39:31.454 --> 00:39:40.499
3x3 뿐만 아니라 5x5 conv와 pooling layer에서도
동일한 작용을 하게됩니다.

00:39:41.562 --> 00:39:51.214
그렇다면 이제 전체 계산량을 계산해봅시다.
현재는 1x1 conv가 추가된 상태입니다.

00:39:51.214 --> 00:40:02.499
계산해보면 전체 358M번의 연산을 수행합니다.
기존의 854M보다 훨씬 줄어든 셈입니다.

00:40:02.499 --> 00:40:10.438
이를 통해 배울 수 있는 점은 1x1 conv를 이용하면
계산량을 조절할 수 있다는 사실입니다.

00:40:10.438 --> 00:40:12.118
질문있나요?

00:40:12.118 --> 00:40:15.535
[학생이 질문]

00:40:23.525 --> 00:40:30.979
질문은 "1 x 1 Conv를 수행하면 일부 정보손실이
발생하지 않는지" 입니다.

00:40:30.979 --> 00:40:35.112
정보 손실이 발생할 수는 있습니다.

00:40:35.112 --> 00:40:46.013
그러나 동시에 redundancy가 있는 input features를 선형결합
한다고 볼 수 있습니다. 1x1 conv로 선형결합을 하고

00:40:47.623 --> 00:40:59.422
non-linearity를 추가하면(ReLU같은) 네트워크가 더 깊어지는
효과도 있습니다. 이것이 엄밀한 해석은 아닙니다. 하지만

00:40:59.422 --> 00:41:07.314
일반적으로 1x1 conv를 추가하면 여러모로 도움이 되고 더 잘 동작합니다.

00:41:07.314 --> 00:41:15.627
Inception Module에서 1 x 1 convs를 사용하는
기본적인 이유는 계산복잡도를 조절하기 위해서입니다.

00:41:15.627 --> 00:41:20.450
GooleNet은 Inception module들을 쌓아올려 구성합니다.

00:41:20.450 --> 00:41:22.827
가운데 그림이 완전한 모습의 inception architecture 입니다.

00:41:22.827 --> 00:41:32.773
GoogLeNet을 더 깊게 알아봅시다. 우선 슬라이드에
안맞아서 그림을 돌려놨습니다.

00:41:32.773 --> 00:41:41.867
GoogLeNet의 앞단(stem) 에는 일반적인 네트워크구조 입니다.
초기 6개의 레이어는 지금까지 봤던 일반적인 레이어들이죠

00:41:43.256 --> 00:41:48.570
처음에는 conv pool을 몇 번 반복합니다.

00:41:48.570 --> 00:41:54.911
이 후에는 Inception module에 쌓이는데
모두 조금씩 다릅니다.

00:41:54.911 --> 00:41:58.433
그리고 마지막에는 classifier 결과를 출력합니다.

00:41:58.433 --> 00:42:08.982
GoogLeNet에서는 계산량이 많은 FC-layer를 대부분 걷어냈고
파라미터를가 줄어들어도 모델이 잘 동작함을 확인했습니다.

00:42:08.982 --> 00:42:17.098
그리고 여기 보시면 추가적인 줄기가 뻗어있는데
이들은 보조분류기(auxiliary classifier) 입니다.

00:42:18.866 --> 00:42:23.273
그리고 이것들은 또한 당신이 알고있는
단지 작은 미니 네트워크들입니다.

00:42:23.273 --> 00:42:29.217
Average pooling과 1x1 conv가 있고
FC-layey도 몇개 붙습니다.

00:42:29.217 --> 00:42:35.702
그리고 SoftMax로 1000개의 ImageNet class를 구분합니다.

00:42:35.702 --> 00:42:41.350
그리고 실제로 이 곳에서도
ImageNet trainset loss를 계산합니다.

00:42:41.350 --> 00:42:51.752
네트워크의 끝에서 뿐만 아니라 이 두 곳에서도 Loss를
계산하는 이유는 네트워크가 깊기 때문입니다.

00:42:51.752 --> 00:43:02.140
보조분류기를 중간 레이어에 달아주면
추가적엔 그레디언트를 얻을 수 있고

00:43:02.140 --> 00:43:13.484
따라서 중간 레이어의 학습을 도울 수 있습니다.

00:43:13.484 --> 00:43:20.711
전체 아키텍쳐의 모습입니다.
가중치를 가진 레이어는 총 22개입니다.

00:43:20.711 --> 00:43:29.474
각 Inception Module은 1x1/3x3/5x5 conv layer를
병렬적으로 가지고있습니다.

00:43:29.474 --> 00:43:44.128
GoogLeNet은 아주 신중하게 디자인된 모델입니다. 모델 디자인의
일부는 앞서 말씀드린 직관들에서 비롯된 것들이고,

00:43:44.128 --> 00:43:55.511
일부는 Google의 거대한 클러스터를 이용한 cross validation을
수행한 결과 나온 최적의 디자인이기도합니다.

00:43:55.511 --> 00:43:57.105
질문있나요?

00:43:57.105 --> 00:44:00.522
[학생이 질문]

00:44:24.442 --> 00:44:32.457
질문은 "보조분류기에서 나온 결과를 최종 분류결과에
이용할 수 있는지" 입니다.

00:44:32.457 --> 00:44:39.164
GoogLeNet 학습 시, 각 보조분류기의 Loss를 모두 합친
평균을 계산합니다. 아마도 도움일 될 것입니다.

00:44:39.164 --> 00:44:49.272
최종 아키텍쳐에서 보조분류기의 결과를 사용하는지 정확히 기억이
나지 않습니다만 충분히 가능성 있습니다. 한번 확인해 보시기 바랍니다.

00:44:49.272 --> 00:44:52.689
[학생이 질문]

00:44:58.352 --> 00:45:10.219
질문은 "bottleneck layer를 구성할 때 1x1 conv 말고
다른 방법으로 차원을 축소시켜도 되는지" 입니다.

00:45:10.219 --> 00:45:17.138
여기에서 1x1 conv를 쓴 이유는 차원 축소의 효과도 있고
다른 레이어들처럼 conv layer이기 때문입니다.

00:45:17.138 --> 00:45:26.180
차원 축소 과정에서 이전의 feature map와 연관이 있는지 학습하려면
전체 네트워크를 Backprop으로 학습시킬 수 있어야 합니다.

00:45:28.601 --> 00:45:30.730
질문있나요?

00:45:30.730 --> 00:45:34.147
[학생이 질문]

00:45:35.807 --> 00:45:42.549
질문은 "각 레이어가 가중치를 공유하는지 아닌지" 입니다.

00:45:42.549 --> 00:45:45.542
네 모든 레이어를 가중치를 공유하지 않습니다.

00:45:45.542 --> 00:45:46.690
질문있나요?

00:45:46.690 --> 00:45:50.107
[학생이 질문]

00:45:56.784 --> 00:46:00.143
질문은 "왜 앞선 레이어에서 그레디언트를
전달해야만 하는지" 입니다.

00:46:00.143 --> 00:46:07.785
네트워크의 맨 마지막에서부터 Chain rule을 이용해서
그레디언트가 전달된다고 생각해봅시다.

00:46:09.599 --> 00:46:21.178
네트워크가 엄청 깊은 경우에서는 그레디언트 신호가
점점 작아지게 되고 결국에는 0에 가깝게 될 수 있습니다.

00:46:21.178 --> 00:46:28.377
그렇기 때문에 보조 분류기를 이용해서 추가적인
그레디언트 신호를 흘려줍니다.

00:46:28.377 --> 00:46:32.667
[학생이 질문]

00:46:32.667 --> 00:46:35.853
질문은 "backprob을 각 보조분류기에서 별도로 여러번 수행하는지"
입니다.

00:46:35.853 --> 00:46:41.446
아닙니다. backprob은 한번만 합니다.
어떤 식으로 생각하시면 되냐면

00:46:41.446 --> 00:46:48.075
computational graph 상에 서로 다른 출력이 있는 것인데

00:46:48.075 --> 00:46:54.004
각 출력에서의 gradient를 모두 계산한 다음
한번에 Backprop을 합니다.

00:46:54.004 --> 00:46:58.970
마치 computational graph 상에 다 함께 있는 것 처럼
생각하고 계산한다고 보시면 됩니다.

00:46:58.970 --> 00:47:05.423
진도가 많이 남았으므로 질문은 수업종료 후
해주시기 바랍니다.

00:47:07.353 --> 00:47:10.520
GoogLeNet에는 기본적으로 22개의 레이어가 있습니다.

00:47:11.441 --> 00:47:15.983
아주 효율적인 Inception module이 있고
FC Layer를 들어냈습니다

00:47:15.983 --> 00:47:22.026
AlexNet보다 12배 작은 파라미터를 가지고있고
GoogLeNet은 ILSVRC 2014 clssification의 우승자이죠

00:47:25.228 --> 00:47:30.869
자 그럼 2015년도의 우승자를 살펴보겠습니다.
ResNet이 바로 그 주인공입니다.

00:47:30.869 --> 00:47:38.339
ResNet은 혁명적으로 네트워크의 깊이가 깊어진 모델입니다.
2014년부터 네트워크가 깊어지긴 했지만

00:47:38.339 --> 00:47:45.616
ResNet 아키텍쳐는 152 레이어로 엄청나게 더 깊어졌죠

00:47:45.616 --> 00:47:48.846
지금부터는 ResNet에 대해서 조금 더 알아보겠습니다.

00:47:48.846 --> 00:47:54.286
ResNet 아키텍쳐는 엄청나게 깊은 네트워크입니다.
기존의 어떤 네트워크보다도 훨씬 더 깊습니다

00:47:54.286 --> 00:48:00.479
ResNet는 residual connections 라는 방법을 사용합니다.
지금부터 논의해볼 주제입니다.

00:48:00.479 --> 00:48:04.158
ImageNet데이터를 분류하기 위해 ResNet은
152개의 레이어를 가지고 있습니다.

00:48:04.158 --> 00:48:07.969
그리고 ILSVRC'15에서 3.57% top5 error를 기록했습니다.

00:48:07.969 --> 00:48:18.114
그리고 아주 놀랍게도 이들은 ResNet 하나로 ImageNet과 COCO
classification/detection 대회를 모조리 휩쓸었습니다.

00:48:18.114 --> 00:48:23.546
그리고 다른 참가자들보다 월등히 우수했습니다.

00:48:25.055 --> 00:48:32.538
자 그럼 ResNet과 residual connection의
기본 Motivation에 대해서 알아봅시다

00:48:32.538 --> 00:48:41.939
그들이 처음 시작한 질문은 바로 일반 CNN을
깊고 더 깊게 쌓게되면 어떤 일이 발생할지였습니다.

00:48:41.939 --> 00:48:53.874
가령 VGG에 conv pool 레이어를 깊게만 쌓는다고
과연 성능이 더 좋아지는 것일까요?

00:48:55.601 --> 00:48:58.421
대답은 NO 입니다.

00:48:58.421 --> 00:49:06.599
네트워크가 깊어지면 어떤 일이 발생하는지 살펴보겠습니다.
20레이어/56레이어의 네트워크를 한번 비교해보죠

00:49:09.498 --> 00:49:16.817
두 모델 다 평범한(plain) CNN입니다. 오른쪽의 test error의
경우는 56 레이어가 20 레이어보다 안좋습니다.

00:49:16.817 --> 00:49:19.771
더 깊은 네트워크가 더 않좋을 수도 있겠구나 싶을 수 있습니다.

00:49:19.771 --> 00:49:29.680
하지만 Training Error가 조금 이상합니다.  다시한번
20/56 레이어를 한번 비교해보겠습니다

00:49:29.680 --> 00:49:40.271
여러분에게 56 레이어 네트워크가 있다면 당연히 엄청나게
많은 파라미터가 있으니 Orverfit하겠구나 를 예상하실 것입니다.

00:49:41.294 --> 00:49:48.985
그리고 overfit이 발생한다면 test error는 높더라도
training error는 아주 낮아야 정상일 것입니다.

00:49:48.985 --> 00:49:55.511
그런데 56 레이어 네트워크의 traing error을 보자하니
20 레이어보다 안좋습니다.

00:49:56.833 --> 00:50:01.545
따라서 더 깊은 모델임에도 test 성능이 낮은 이유가
over-fitting때문이 아니라는 것을 알 수 있습니다.

00:50:03.462 --> 00:50:10.253
ResNet 저자들이 내린 가설은 더 깊은 모델 학습 시
optimization에 문제가 생긴다는 것입니다.

00:50:10.253 --> 00:50:15.611
모델이 깊어질수록 최적화가 어렵다는 가설이죠

00:50:16.835 --> 00:50:23.263
그들은 "모델이 더 깊다면 적어도 더 얕은 모델만큼은
성능이 나와야 하지 않은지"라고 추론했습니다.

00:50:23.263 --> 00:50:32.330
가령 이런 해결책을 생각해 볼 수 있습니다. 우선 더 얕은 모델의
가중치를 깊은 모델의 일부 레이어에 복사합니다.

00:50:32.330 --> 00:50:35.192
그리고 나머지 레이어는 identity mapping을 하는 것이죠
(input을 output으로 그냥 내보냄)

00:50:35.192 --> 00:50:39.533
이렇게 구성하면 shallower layer 만큼의 성능을 나와야겠죠

00:50:39.533 --> 00:50:46.295
Deeper Model의 학습이 제대로 안되더라도
적어도 Shallow Model 만큼의 성능은 보장됩니다.

00:50:46.295 --> 00:51:00.594
그렇다면 이 motivation을 우리가 만들 모델에 녹이려면
어떻게 모델 아키첵쳐를 디자인해야할까요?

00:51:00.594 --> 00:51:11.794
그들의 아이디어는 레이어를 단순하게 쌓지 않는 것입니다.

00:51:11.794 --> 00:51:21.708
Direct mapping 대신에 Residual mapping을 하도록
이런 식으로 블럭을 쌓는 것이죠

00:51:21.708 --> 00:51:28.220
오른쪽 그림을 봅시다. 우선 입력은 그저
이전 레이어에서 흘러들어온 입력입니다.

00:51:29.818 --> 00:51:48.499
그리고 레이어가 직접 "H(x)"를 학습하기 보다
이런 식으로 "H(x) - x" 를 학습할 수 있도록 만들어줍니다.

00:51:49.450 --> 00:51:55.827
이를 위해서 Skip Connection을 도입하게 됩니다.
오른쪽의 고리모양 보이시죠

00:51:55.827 --> 00:52:07.241
오른쪽의 Skip Connection은 가중치가 없으며 입력을
identity mapping으로 그대로 출력단으로 내보냅니다.

00:52:07.241 --> 00:52:12.562
그러면 실제 레이어는 변화량(delta) 만 학습하면 됩니다.
입력 X에 대한 잔차(residual) 이라고 할 수 있죠

00:52:14.067 --> 00:52:24.502
최종 출력 값은 "input X + 변화량(Residual)" 입니다.

00:52:24.502 --> 00:52:31.428
이 방법을 사용하면 학습이 더 쉬워집니다.
가령 Input = output 이어야 하는 상황이라면

00:52:32.510 --> 00:52:39.249
레이어의 출력인 F(x)가 0 이어야 하므로(residual = 0)
 모든 가중치를 0으로 만들어주면 그만입니다.

00:52:39.249 --> 00:52:48.578
손쉽게 출력을 Identity로 만들어 줄 수 있는 것이죠. 이 방법을
사용하면 앞서 제시한 방법을 손쉽게 구성할 수 있습니다.

00:52:48.578 --> 00:53:00.962
네트워크는 Residual만 학습하면 그만입니다.
출력 값도 결국엔 입력 입력 X에 가까운 값입니다.

00:53:00.962 --> 00:53:05.388
다만 X를 조금 수정한 값이죠. 레이어가 Full mapping을
학습하기 보다 이런 조금의 변화만 학습하는 것입니다.

00:53:05.388 --> 00:53:08.249
질문있나요?

00:53:08.249 --> 00:53:09.189
[학생이 질문]

00:53:09.189 --> 00:53:12.689
질문은 "레이어의 출력과 Skip Connection의
출력이 같은 차원인지" 입니다.

00:53:13.770 --> 00:53:17.603
그렇습니다. 두 경로의 출력 값 모두 같은 차원입니다.

00:53:18.752 --> 00:53:32.288
일반적으로는 같은 차원이 맞지만, 그렇지 않은 경우에는
Depth-wise padding으로 차원을 맞춰 줍니다.

00:53:32.288 --> 00:53:33.395
질문있나요?

00:53:33.395 --> 00:53:39.120
[학생이 질문]

00:53:45.857 --> 00:53:53.638
질문은 "레이어의 출력이 Residual 이라는 것이
뜻하는 바가 정확히 무엇인지" 입니다.

00:53:53.638 --> 00:54:01.899
여기 전체 출력 값인 "F(x) + X" 를 다시한번 살펴봅시다.
F(x)는 레이어의 출력 값입니다.

00:54:01.899 --> 00:54:06.650
그리고 X는 그저 입력 값이죠.

00:54:06.650 --> 00:54:17.198
왼쪽의 평범한(Plain) 네트워크는 H(x)를 학습하고 있습니다.
하지만 앞서 보았듯 H(x)를 학습시키는 것은 너무 어렵습니다.

00:54:17.198 --> 00:54:20.671
아주 깊은 네트워크에서는 H(x)를
잘 학습시키기가 아주 어려운 것이죠.

00:54:20.671 --> 00:54:29.438
ResNet의 아이디어는 H(x) = F(x) + X 이니
F(x)를 학습시켜보면 어떨까? 하는 것입니다.

00:54:29.438 --> 00:54:39.741
H(x)를 직접 배우는 대신에 X에 얼마의 값을 더하고 빼야
할까?(Residual)를 배우는 것이 쉬울 것이라고 생각한 것이죠

00:54:39.741 --> 00:54:45.889
입력값을 어떻게 수정해야 하는지를 배운다고 보시면 됩니다.

00:54:45.889 --> 00:54:49.121
[학생이 질문]

00:54:49.121 --> 00:54:58.129
질문은 "F(x) 가 Residual 인지" 입니다. 맞습니다.
F(x)가 Residual 입니다.

00:55:01.477 --> 00:55:03.941
질문있나요?

00:55:03.941 --> 00:55:07.441
[학생이 질문]

00:55:11.319 --> 00:55:20.145
질문은 "실제로 F(x)와 x를 단순히 더하는 것인지 별도의 방법이 있는지"
입니다. 그냥 더하시면 됩니다.

00:55:20.145 --> 00:55:28.809
F(x)는 단순히 X에 값을 얼마나 더거나 빼야 하는지를
나타내므로 단순하게 더하기만 하시면 됩니다.

00:55:30.652 --> 00:55:34.463
Main intuition을 어느정도 이해하셨나요?

00:55:34.463 --> 00:55:35.361
질문있나요?

00:55:35.361 --> 00:55:38.778
[학생이 질문]

00:55:40.721 --> 00:55:47.099
질문은 "왜 Direct mapping(H(x))을 학습하는 것 보다
Residual(F(x))을 학습하는 것이 쉬운지" 입니다.

00:55:47.099 --> 00:55:58.747
그것은 단지 그들이 제시한 "가설" 일 뿐입니다. Residual을 학습
시키는 것은 X에 대한 변화량(delda)을 학습시키는 것입니다.

00:55:58.747 --> 00:56:16.101
만약 가설이 참이라면, 내 모델의 일부는 학습된 shallow layers이고
나머지 레이어들은 Identity라면 잘 동작해야만 합니다.

00:56:16.101 --> 00:56:23.985
이는 대부분의 레이어가 잘 동작하려면 레이어의 출력이
Identity에 가까워야 할지 모른다는 것을 암시합니다.

00:56:23.985 --> 00:56:30.954
이 때문에
Identity(Input) + 변화량(delta) 만 학습시키면 됩니다.

00:56:30.954 --> 00:56:34.315
그리고 가령 Output = Input (identity)
이어야만 하는 상황이면

00:56:34.315 --> 00:56:40.363
F(x) = 0 이 되면 그만입니다. 이는 상대적으로
학습시키기 쉽다고 볼 수 있습니다.

00:56:40.363 --> 00:56:44.784
이런 방식으로 Identity Mapping에
가까운 값을 얻을 수 있습니다.

00:56:44.784 --> 00:56:50.966
하지만 그들의 직관과 가설이 입증된 바는 없습니다.

00:56:50.966 --> 00:56:58.708
그리고 나중에 보시겠지만, 일부 사람들은 residuals가
필요 없다고 주장하기도 합니다.

00:56:58.708 --> 00:57:07.507
적어도 ResNet에서 주장하고 있는 그 "가설"이 불필요하다고
말이죠 하지만 실제로는 ResNet을 쓰면 성능이 더 좋아집니다.

00:57:07.507 --> 00:57:08.810
질문있나요?

00:57:08.810 --> 00:57:12.227
[학생이 질문]

00:57:41.813 --> 00:57:49.128
질문은 "이전에도 ResNet처럼 레이어의 입/출력을 합치는
연구가 있었는지" 입니다.

00:57:49.128 --> 00:57:56.747
예 그렇습니다. 네트워크의 구성과 연결구조는
아주 활발하게 연구되고있는 분야입니다.

00:57:56.747 --> 00:58:04.695
아마도 나중에 다른 네트워크 아키텍쳐의 예시도 간단하게 살펴볼
예정입니다. 아주 활발히 연구되는 분야이죠

00:58:05.658 --> 00:58:12.093
좋습니다. 기본적으로 ResNet은 residual block들을
쌓아 올리는 구조입니다.

00:58:12.093 --> 00:58:14.788
여기 전체 ResNet 아키텍쳐를 보실 수 있습니다.

00:58:14.788 --> 00:58:27.299
하나의 Residual blocks는 두 개의 3x3 conv layers로
이루어져 있습니다. 이렇게 구성해야 잘 동작하는 것으로 알려져있습니다.

00:58:27.299 --> 00:58:29.828
이 Residual blocks를 아주 깊게 쌓아 올립니다.

00:58:29.828 --> 00:58:40.851
ResNet은 150 Layers까지 쌓아 올릴 수 있습니다.

00:58:46.582 --> 00:58:53.982
그리고 주기적으로 필터를 두배 씩 늘리고
stride 2를 이용하여 Downsampling을 수행합니다.

00:58:55.856 --> 00:59:03.867
그리고 네트워크의 초반에는 Conv Layer가 추가적으로 붙고
네트워크의 끝에는 FC-Layer가 없습니다.

00:59:03.867 --> 00:59:08.641
대신 Global Average Pooling Layer 를 사용합니다.
GAP는 하나의 Map 전체를 Average Pooling 합니다.

00:59:08.641 --> 00:59:12.808
그리고 마지막에는 1000 개의 클래스분류를 위한 노드가 붙습니다.

00:59:14.694 --> 00:59:16.991
여기 까지가 전체 ResNet 아키텍쳐입니다.

00:59:16.991 --> 00:59:21.935
ResNet은 아주 심플하면서도 세련된 모델입니다.
ResNet Block을 하나씩 쌓아 올리는 구조입니다.

00:59:21.935 --> 00:59:29.389
ResNet 모델의 Depth는 34, 50, 100 까지 늘어납니다.
논문에서는 ImageNet문제를 위해 152 까지 늘렸습니다.

00:59:34.230 --> 00:59:43.964
그리고 한가지 더 말씀드릴 점은 ResNet의 경우 모델 Depth가
50 이상일 때 Bottleneck Layers를 도입합니다.

00:59:43.964 --> 00:59:46.663
이는 GoogLeNet에서 사용한 방법과 유사합니다.

00:59:46.663 --> 00:59:57.195
Bottleneck Layer는 1x1 conv를 도입하여
초기 필터의 depth를 줄여줍니다.

00:59:57.195 --> 01:00:07.949
가령 입력이 28x28x256 일때 1x1 conv를 적용하면 depth가
줄어들어서 28x28x64 가 됩니다.

01:00:09.107 --> 01:00:18.486
이로인해 3 x 3 conv의 계산량이 줄어듭니다.

01:00:18.486 --> 01:00:29.870
그리고 뒤에 다시 1x1 conv를 추가해서 Depth를 다시
256으로 늘립니다. Deeper ResNet은 이런 구조를 취합니다.

01:00:33.021 --> 01:00:41.282
실제로 ResNet은 모든 Conv Layer 다음 Batch Norm
을 사용합니다. 그리고 초기화는 Xavier를 사용하는데

01:00:41.282 --> 01:00:50.578
추가적인 scaling factor를 추가합니다(2로 나눔). 이 방법은
SGD + Momentum에서 좋은 초기화 성능을 보입니다.

01:00:51.604 --> 01:00:59.470
 learning rate는  learning rate 스케줄링을 통해서
validation error가 줄어들지 않는 시점에서 조금씩 줄여줍니다.

01:01:01.751 --> 01:01:05.874
Minibatch 사이즈는 256이고 weight dacay도 적용합니다.
Dropout은 사용하지 않았습니다.

01:01:07.645 --> 01:01:13.581
실험결과를 보시면  그들은 성능의 열화 없이
Very deep network를 아주 잘 학습시킬 수 있었습니다.

01:01:13.581 --> 01:01:19.060
Backprob시 네트워크의 gradient flow를
아주 잘 가져갈 수 있었습니다.

01:01:19.060 --> 01:01:22.625
ImageNet 학습을 위해서 152 레이어 까지 시도해 보았으며

01:01:22.625 --> 01:01:26.632
Cifar-10 으로는 1200 Layer 까지 늘렸습니다.

01:01:26.632 --> 01:01:35.024
그리고 네트워크가 깊어질수록 Training Error는
더 줄어듦을 알 수 있었습니다.

01:01:36.303 --> 01:01:44.543
깊은 네트워크의 Train Error가 더 높아지는 경우는 없었습니다.

01:01:44.543 --> 01:01:54.843
ResNet은 ILSVRC와 COCO의 모든 대회종목을 휩쓸었습니다.
그것도 2등과의 엄청난 격차로 말이죠

01:01:56.152 --> 01:02:06.649
Total top-5 Error는 3.6% 였습니다. 이 수치는
ImageNet paper에서 제시한 "인간의 성능" 보다 뛰어났죠

01:02:08.902 --> 01:02:22.551
ImageNet Challenge의 "인간의 성능"은 우리 연구실에 있던
Andrej Kapathy가 일주일동안 공들여서 직접 수행했습니다.

01:02:24.730 --> 01:02:34.191
아마 5%대의 결과로 기억합니다.
ResNet의 인간보다 더 잘했습니다.

01:02:36.175 --> 01:02:42.069
ResNet의 최근에 사람들이 아주 많이 사용하는 네트워크입니다.

01:02:42.069 --> 01:02:48.004
처음에 AlexNet부터 살펴보았습니다.
VGGNet과 GooglLeNet은 지금도 여전히 아주 유명합니다.

01:02:48.004 --> 01:02:58.218
하지만 ResNet이 단연 가장 최신에 나왔고 성능이 제일 좋았습니다.
여러분이 성능좋은 네트워크를 찾는다면 ResNet은 아주 좋은 선택입니다.

01:03:00.154 --> 01:03:06.403
자 그럼 모델 별 complexity를 빠르게 한번 살펴보겠습니다.

01:03:06.403 --> 01:03:14.120
왼쪽 그래프는 모델의 성능 별로 정렬해 보았습니다 .
Top-1 Accuracy가 기준이고 높을수록 좋은 모델입니다.

01:03:15.275 --> 01:03:21.540
거의 모두 우리가 지금까지 배운 모델이거나 조금 변형된
모델들 입니다. 가령 GoogLe-inception을 보시면

01:03:21.540 --> 01:03:31.389
이 모델은 버전별로 V2, V3 등이 있는데 가장 좋은 모델은 바로 여기
V4 입니다. ResNet + Inception 모델입니다.

01:03:31.389 --> 01:03:39.159
모델이 조금 조금씩 점점 바뀌었고 결국
가장 좋은 모델을 차지했습니다.

01:03:39.159 --> 01:03:45.446
자 이제는 오른쪽 그래프를 살펴봅시다.
계산 복잡성이 추가되었습니다.

01:03:47.686 --> 01:03:52.313
Y축은 top-1 Accuracy이고 높을수록 좋습니다.

01:03:52.313 --> 01:04:03.074
X축은 연산량을 나타냅니다. 오른쪽으로 갈수록 연산량이 많습니다.
원의 크기는 메모리 사용량입니다. 원이 클수록 덩치가 큰 모델이죠.

01:04:03.074 --> 01:04:07.251
오른쪽 아래 회색 원을 참고하시면 됩니다.
원이 점점 커질수록 메모리 사용량도 점점 커집니다.

01:04:07.251 --> 01:04:16.206
초록색 원이 VGGNet입니다. 가장 효율성이 작습니다.
메모리도 엄청 잡아먹고 계산량도 엄청 많죠

01:04:16.206 --> 01:04:18.623
하지만 어쨌든 성능은 나쁘지 않습니다.

01:04:19.838 --> 01:04:29.275
GoogLeNet이 가장 효율적인 네트워크입니다. x축에서
거의 왼쪽에 있죠 뿐만 아니라 메모리 사용도 적습니다.

01:04:29.275 --> 01:04:39.411
초기 모델인 AlexNet은 Accuracy가 낮습니다. 몸집이 작은지라
계산량도 작죠.하지만 메모리사용량은 아주 비효율적입니다.

01:04:41.309 --> 01:04:46.216
ResNet의 경우는 적당한 효율성을 가지고있습니다.

01:04:46.216 --> 01:04:52.500
메모리 사용량과 계산량을 중간정도이지만
Accuracy는 최상위입니다.

01:04:56.029 --> 01:04:58.028
다른 그래프를 몇가지 더 보여드리겠습니다.

01:04:58.028 --> 01:05:14.868
왼쪽 그래프는 forward pass 시간입니다. 단위는 ms 인데
VGG가 제일 오래걸립니다. 200ms으로 초당 5정도 처리할 수 있겠군요

01:05:14.868 --> 01:05:25.883
오른쪽은 전력소모량인데 더 자세한 내용은 아래 논문을
참고하시기 바랍니다. 더 다양한 분석 결과를 보실 수 있습니다.

01:05:30.604 --> 01:05:38.750
지금까지 보신 아키텍쳐이 아주 중요합니다.
반드시 깊게 잘 알아야 하고 익숙해져야 합니다.

01:05:38.750 --> 01:05:48.263
이제는 아키텍쳐 몇 가지를 더 소개시켜 드리겠습니다. 역사적으로
의미가 있거나, 최신 연구분야에 속하는 것들입니다.

01:05:50.716 --> 01:05:56.342
자 우선 Network in Network 입니다.
2014년에 나온 논문입니다.

01:06:00.529 --> 01:06:16.118
Network in Network의 기본 아이디어는 MLP conv layer
입니다. 네트워크 안에 작은 네트워크를 삽입하는 것이죠

01:06:16.118 --> 01:06:23.152
각 Conv layer 안에 MLP(Multi-Layer Perceptron)
를 쌓습니다. FC-Layer 몇 개를 쌓는 것이죠

01:06:23.152 --> 01:06:29.167
맨 처음에는 기존의 Conv Layer가 있고 FC-Layer를 통해
abstract features를 잘 뽑을수 있도록 합니다.

01:06:29.167 --> 01:06:41.975
단순히 conv filter만 사용하지 말고, 조금 더 복잡한 계층을
만들어서 activation map을 얻어보자는 아이디어입니다.

01:06:41.975 --> 01:06:47.941
NIN에서는 기본적으로는 FC-Layer를 사용합니다.
이를 1x1 conv layer 라고도 합니다.

01:06:47.941 --> 01:06:57.196
아래의 다이어그램이 바로 Network in Network 구조입니다.

01:06:57.196 --> 01:07:10.102
Network in Network는 GoogLeNet과 ResNet보다 먼저
Bottleneck 개념을 정립했기 때문에 아주 의미있는 아이디어입니다.

01:07:10.102 --> 01:07:22.070
또한 GoogLeNet은 NIN와 구조는 조금 다르지만
NIN의 "철학적인 영감" 을 받았습니다.

01:07:24.238 --> 01:07:36.759
자 다음은 ResNet과 관련된 일련의 연구들을 소개해 드리겠습니다.
ResNet의 성능을 향상시킨 최근의 연구들입니다.

01:07:36.759 --> 01:07:39.911
이 쪽이 워낙 빠르게 변하고 있어서
저도 깊게 아는 내용은 아닙니다.

01:07:39.911 --> 01:07:44.754
자세한 내용은 여러분이 직접 논문을 찾아보시기 바랍니다.

01:07:45.755 --> 01:07:55.719
2016년 ResNet의 저자들은 ResNet의
블록 디자인을 향상시킨 논문을 발표했습니다.

01:07:56.742 --> 01:08:03.015
이 논문에서는 ResNet block path를 조절하였습니다.

01:08:03.015 --> 01:08:18.861
새로운 구조는 direct path를 늘려서 정보들이 앞으로 더욱 더 잘
전달되고  Backprob도 더 잘 될 수 있게 개선했습니다.

01:08:18.861 --> 01:08:25.319
이 새로운 Block 구조 덕분에 더 좋은 성능을 얻을 수 있었습니다.

01:08:25.319 --> 01:08:28.959
Wide Residual Network 라는 논문도 있습니다.

01:08:28.959 --> 01:08:40.228
그들이 기존의 ResNet 논문은 깊게 쌓는 것에 열중했지만
사실 중요한 것은 depth가 아닌 residual 이라고 주장했습니다.

01:08:40.228 --> 01:08:45.290
Residual Connection이 있다면
네트워크가 굳이 더 깊어질 필요가 없다고 주장했습니다.

01:08:45.290 --> 01:08:52.794
그래서 그들은 residual block 을 더 넓게 만들었습니다.
즉 conv layer의 필터를 더 많이 추가했습니다.

01:08:52.794 --> 01:09:02.661
가령 기존의 ResNet에는 Block 당 F개의 filter만 있었다면
대신에 F * K 개의 필터로 구성했습니다.

01:09:02.663 --> 01:09:11.502
각 레이어를 넓게 구성했더니 50 레이어만 있어도
152 레이어의 기존 ResNet보다 성능이 좋다는 것을 입증했습니다.

01:09:13.754 --> 01:09:23.035
그리고 네트워크의 Depth 대신에 filter의 Width를 늘리면
추가적인 이점이 있는데, 계산 효율이 증가합니다.

01:09:23.035 --> 01:09:26.922
왜냐하면 병렬화가 더 잘되기 때문입니다.

01:09:26.923 --> 01:09:39.546
네트워크의 Depth를 늘리는 것은 sequential한 증가이기 때문에
conv의 필터를 늘리는(width) 편이 더 효율적입니다.

01:09:39.546 --> 01:09:49.817
이들은 네트워크의 width/depth/residual connection
를 고찰하는 뜻깊은 연구를 하였습니다.

01:09:49.817 --> 01:09:58.125
그리고 비슷한 시점에 등장한 또 하나의 논문이
있습니다. 바로 ResNeXt 입니다.

01:09:58.125 --> 01:10:04.383
이 논문 또한 ResNet의 저자의 논문입니다.
계속해서 ResNet 구조를 밀고 있는 것이죠

01:10:04.383 --> 01:10:18.576
여기에서도 계속 residual block의 width를 파고듭니다.
filter의 수를 늘리는 것이죠

01:10:18.576 --> 01:10:26.415
각 Residual block 내에 "다중 병렬 경로" 추가합니다.
이들은 pathways의 총 합을 cardinality라고 불렀습니다.

01:10:26.415 --> 01:10:36.317
하나의 bottleneck ResNet block은 비교적 작지만
이런 thinner blocks을 병렬로 여러개 묶었습니다.

01:10:38.395 --> 01:10:44.452
여기에서 ResNeXt과 Wide ResNet과의 연관성을 볼 수 있습니다.

01:10:44.452 --> 01:10:54.023
또한 여러 Layers를 병렬로 묶어준다는 점에서
Inception Module과도 연관있습니다.

01:10:54.023 --> 01:10:58.190
ResNeXt 라는 이름 자체가 이를 내포하고 있습니다.
(ResNet + inEXeption)

01:11:00.838 --> 01:11:13.878
ResNet의 성능을 개선하고자 하는 방법은 계속됩니다.
Stochastic Depth 이라는 논문이 있습니다. 주제는 Depth 이죠

01:11:13.878 --> 01:11:21.537
네트워크가 깊어지면 깊어질수록
Vanishing gradient 문제가 발생합니다.

01:11:21.537 --> 01:11:32.071
깊은 네트워크에서는 그레디언트를 뒤로 전달할수록
점점 그레디언트가 작아지는 문제가 있습니다.

01:11:32.071 --> 01:11:43.045
기본 아이디어는 Train time에 레이어의 일부를 제거합니다.
short network면 트레이닝이 더 잘 될 수 있기 때문입니다.

01:11:43.045 --> 01:11:48.436
일부 네트워크를 골라서 identity connection으로 만들어버립니다.

01:11:48.436 --> 01:11:56.126
이렇게 shorter network를 만들어서 Train하면
그레디언트가 더 잘 전달될 수 있겠죠

01:11:56.126 --> 01:12:04.074
아주 효율적인 방법이 될 수 있습니다. Dropout과 유사합니다.
Dropout은 앞선 강의에서 다룬 적 있었죠

01:12:04.074 --> 01:12:08.108
그리고 Test time에서는 full deep network를 사용합니다.

01:12:10.446 --> 01:12:19.038
지금까지 소개시켜 드린 방법들은 ResNet
아키텍쳐를 개선하고자 노력했습니다.

01:12:19.038 --> 01:12:32.253
"Beyond ResNet"을 지향하는 방법들도 있습니다.
Non-ResNets 중에도 ResNet과 견줄만한 성능의 모델들이 있습니다.

01:12:32.253 --> 01:12:45.273
그 중 하나는 FractalNet 입니다. 아주 최근에 나왔습니다.
그들은 residual connection이 쓸모없다고 주장합니다.

01:12:45.273 --> 01:12:52.645
지금까지는 ResNet의 Motivation이 어느정도 납득할만
하다고 생각했지만, FractalNet은 그렇게 생각하지 않습니다.

01:12:52.645 --> 01:12:58.407
FractalNet 아키텍쳐에서는
residual connection이 전혀 없습니다.

01:12:58.407 --> 01:13:03.898
그들은 shallow/deep network의 정보 모두를
잘 전달하는 것이 중요하다고 생각했습니다.

01:13:03.898 --> 01:13:13.258
그래서 FractalNet은는 오른쪽 그림에서 보시는
바와 같이 fractal한 모습입니다.

01:13:14.769 --> 01:13:18.639
FractalNet에서는 shllow/deep 경로를
출력에 모두 연결합니다.

01:13:20.045 --> 01:13:29.568
FractalNet에는 다양한 경로가 존재하지만 Train time에는
Dropout처럼 일부 경로만을 이용해서 Train 합니다.

01:13:29.568 --> 01:13:37.203
그리고 Test time에는 full network를 사용합니다.
그들은 FractalNet의 좋은 성능을  입증했습니다.

01:13:39.047 --> 01:13:44.886
DenseNet 이라는 아키텍쳐도 있습니다.
(DENSEly Connected Convolutional NETworks)

01:13:44.886 --> 01:13:48.567
DenseNet에는 Dense Block 이란 것이 있습니다.

01:13:48.567 --> 01:13:55.940
여기 보시면 한 레이어가 그 레이어 하위의
모든 레이어와 연결되어 있습니다.

01:13:55.940 --> 01:14:00.362
Network의 입력이미지가 모든 Layer의 입력으로 들어갑니다.

01:14:00.362 --> 01:14:08.779
그리고 모든 레이어의 출력이 각 레이어의 출력과 Concat 됩니다.

01:14:08.779 --> 01:14:18.643
그리고 이 값이 각 Conv layer의 입력으로 들어갑니다.
이 과정에서 dimention을 줄여주는 과정이 포함됩니다.

01:14:18.643 --> 01:14:30.863
그리고 이들은 Dense Connection이 Vanishing
gradient 문제를 완화시킬 수 있다고 주장합니다.

01:14:30.863 --> 01:14:37.324
그리고 Dense connection은 Feature를 더 잘 전달하고
더 잘 사용할 수 있게 해줍니다.

01:14:37.324 --> 01:14:45.487
각 레이어의 출력이 다른 레이어에서도
여러번 사용될 수 있기 때문입니다.

01:14:47.906 --> 01:15:03.006
ResNet 스럽지 않지만 ResNets만큼 성능이 좋은 다양한
아키텍쳐들을 살펴보고 있습니다. 아주 활발하게 연구되고 있는 분야입니다.

01:15:03.006 --> 01:15:11.830
그런 네트워크들은 대게는, 레이어 간의 연결을 어떻게 구성할지,
그리고 depth를 어떻게 구성할지에 관한 연구가 많습니다.

01:15:13.528 --> 01:15:17.991
그리고 마지막으로 말씀드릴 네트워크는
"효율성" 게 치중한 네트워크입니다.

01:15:17.991 --> 01:15:33.994
GoogLeNet은 효율적인 모델에 대한 방향을 제시했습니다.
practical usage 를 위해서는 아주 중요한 주제입니다.

01:15:33.994 --> 01:15:37.927
효율성을 강조하는 또 하나의 모델이 있습니다.
바로 SqueezeNet 입니다.

01:15:37.927 --> 01:15:41.618
아주 효율적인 네트워크입니다. 그들은
fire modules 이라는 것을 도입했습니다. fire modules 의-

01:15:41.618 --> 01:15:49.645
 "squeeze layer"는 1x1 필터들로 구성되고, 이 출력 값이
1x1/3x3 필터들로 구성되는 "expand layer"의 입력이 됩니다.

01:15:49.645 --> 01:15:59.220
SqueezeNet는 ImageNet에서 AlexNet 만큼의
Accuracy를 보이지만 파라미터는 50배 더 적었습니다.

01:15:59.220 --> 01:16:06.093
그리고 SqueezeNet을 더 압축하면 AlexNet보다
500배 더 작아지게 됩니다.

01:16:06.093 --> 01:16:10.095
SqueezeNet의 용량은 0.5Mb 밖에 안되죠

01:16:10.095 --> 01:16:20.062
Model Compression과 관련해서는 나중에 더 다루도록 하겠습니다.

01:16:21.856 --> 01:16:26.809
오늘 배운 내용을 요약해보겠습니다. 오늘은
다양한 종류의 CNN 아키텍쳐를 배웠습니다.

01:16:26.809 --> 01:16:31.555
4가지 주요 아키텍쳐를 배웠습니다.
여러분들이 아주 많이 사용하게 될 모델들이죠

01:16:31.555 --> 01:16:35.553
AlexNet는 초창기에 아주 유명했던 네트워크입니다.

01:16:35.553 --> 01:16:38.832
VGG과 GoogleNet은 지금도 여전히 널리 사용됩니다.

01:16:38.832 --> 01:16:45.906
아마 ResNet 을 가장 많이 사용할 지 모르겠네요

01:16:45.906 --> 01:16:50.587
그리고 그 밖에 다른 네트워크들도 살펴보았습니다.

01:16:51.921 --> 01:16:58.228
Model zoo가 있으니 필요할 때 마다 언제든지
이런 모델들을 가져다 쓸 수 있습니다.

01:16:58.228 --> 01:17:06.827
그리고 네트워크가 점점 깊어지는 트렌드가 있긴 하나
어떻게 레이어를 디자인할지가 가장 큰 관심사였습니다.

01:17:06.827 --> 01:17:15.419
skip connections 등 말이죠.
그리고 Backprob이 잘 되도록 디자인하는 것도 중요했습니다.

01:17:15.419 --> 01:17:22.748
그리고 Depth vs Width, residual connection 등
다양한 이슈를 다뤄보았습니다.

01:17:22.748 --> 01:17:31.380
서로 어떤 Trade off가 존재하는지는 지금도 아주 활발하게
연구되는 분야입니다. 여러분도 계속 지켜보시기 바랍니다.

01:17:31.380 --> 01:17:33.597
다음 시간에는 Recurrent Neural Networks
에 대해서 배워보도록 하겠습니다.